home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
objtools
/
subdiv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
4KB
|
199 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* subdiv -
* Sub-divide triangles to some tolerance.
*
* Paul Haeberli - 1990
*/
#include "stdio.h"
#include "math.h"
#include "vect.h"
#include "sgiobj.h"
sgiobj *subdiv();
main(argc,argv)
int argc;
char **argv;
{
sgiobj *obj;
float tol;
if(argc<4) {
fprintf(stderr,"usage: subdiv in.sgo out.sgo tol\n");
exit(1);
}
obj = readsgiobj(argv[1]);
tol = atof(argv[3]);
obj = subdiv(obj,tol);
writesgiobj(argv[2],obj);
exit(0);
}
/*
* subdiv stuff follows
*
*/
typedef struct tri {
struct tri *next;
float data[3*PNTLONGS];
} tri;
static tri *tlist;
int ntri;
sgiobj *subdiv(obj,tol)
sgiobj *obj;
float tol;
{
int npolys;
float *fptr;
sgiobj *sobj;
tri *tptr;
if(obj->objtype != OBJ_TRILIST) {
fprintf(stderr,"subdiv: objject must be triangle list\n");
exit(1);
}
fptr = (float *)obj->data;
npolys = (obj->nlongs/PNTLONGS)/3;
printf("npolys in %d\n",npolys);
while(npolys--) {
subdivtri(fptr+(0*PNTLONGS),fptr+(1*PNTLONGS),fptr+(2*PNTLONGS),tol);
fptr += 3*PNTLONGS;
}
sobj = newtriobj(ntri);
fptr = (float *)sobj->data;
tptr = tlist;
printf("npolys out %d\n",ntri);
while(tptr) {
bcopy(tptr->data,fptr,3*PNTLONGS*sizeof(float));
fptr += 3*PNTLONGS;
tptr = tptr->next;
}
return sobj;
}
#define NONE 0x0
#define D0 0x1
#define D1 0x2
#define D2 0x4
subdivtri(v0,v1,v2,tol)
float *v0, *v1, *v2;
float tol;
{
float d0, d1, d2;
float i0[PNTLONGS];
float i1[PNTLONGS];
float i2[PNTLONGS];
vect d;
int code;
vsub(v0+OFFSET_POINT,v1+OFFSET_POINT,&d);
d0 = vlength(&d);
vsub(v1+OFFSET_POINT,v2+OFFSET_POINT,&d);
d1 = vlength(&d);
vsub(v2+OFFSET_POINT,v0+OFFSET_POINT,&d);
d2 = vlength(&d);
code = NONE;
if(d0>tol)
code |= D0;
if(d1>tol)
code |= D1;
if(d2>tol)
code |= D2;
switch(code) {
case NONE:
outtri(v0,v1,v2);
break;
case D0:
plerp(v0,v1,i0);
subdivtri(v0,i0,v2,tol);
subdivtri(v2,i0,v1,tol);
break;
case D1:
plerp(v1,v2,i0);
subdivtri(v1,i0,v0,tol);
subdivtri(v0,i0,v2,tol);
break;
case D2:
plerp(v2,v0,i0);
subdivtri(v2,i0,v1,tol);
subdivtri(v1,i0,v0,tol);
break;
case D0|D1:
plerp(v0,v1,i0);
plerp(v1,v2,i1);
subdivtri(v0,i0,v2,tol);
subdivtri(v2,i0,i1,tol);
subdivtri(v1,i1,i0,tol);
break;
case D1|D2:
plerp(v1,v2,i0);
plerp(v2,v0,i1);
subdivtri(v1,i0,v0,tol);
subdivtri(v0,i0,i1,tol);
subdivtri(v2,i1,i0,tol);
break;
case D2|D0:
plerp(v2,v0,i0);
plerp(v0,v1,i1);
subdivtri(v2,i0,v1,tol);
subdivtri(v1,i0,i1,tol);
subdivtri(v0,i1,i0,tol);
break;
case D2|D1|D0:
plerp(v0,v1,i0);
plerp(v1,v2,i1);
plerp(v2,v0,i2);
subdivtri(v0,i0,i2,tol);
subdivtri(v1,i1,i0,tol);
subdivtri(v2,i2,i1,tol);
subdivtri(i0,i1,i2,tol);
break;
}
}
plerp(v0,v1,l)
float *v0, *v1, *l;
{
int i;
for(i=0; i<PNTLONGS; i++)
*l++ = (*v0++ + *v1++)/2.0;
}
outtri(v0,v1,v2)
float *v0, *v1, *v2;
{
tri *t;
float *fptr;
t = (tri *)malloc(sizeof(tri));
fptr = t->data;
bcopy(v0,fptr,PNTLONGS*sizeof(float));
fptr += PNTLONGS;
bcopy(v1,fptr,PNTLONGS*sizeof(float));
fptr += PNTLONGS;
bcopy(v2,fptr,PNTLONGS*sizeof(float));
t->next = tlist;
tlist = t;
ntri++;
}